/**
 * @file Statistics.h
 * @author shikang999@126.com
 * @brief 这个类主要用于统计每次测试数据结果
 * @version 0.1
 * @date 2025-06-21
 * 
 * @copyright Copyright (c) 2025
 * 
 */

#include "BaseFun.h"
#include "BaseSolver.h"

namespace Solver
{

//1. 定义每次单个测试案例
struct Case_t
{
    Case_t():index(0), dateTime(0), costTime(0), iterNum(0), y(0)
    {

    }

    uint32_t index;      //第几轮测试
    uint64_t dateTime;   //案例测试日期, 日期格式为 20250618093456 ,即 2025/06/18 09:34:56
    uint32_t costTime;   //求解耗时,单位为秒
    uint32_t iterNum;    //迭代次数

    value_t y;           //最终优化目标值
    VectorXd_t x;        //最终优化参数
    vecValue_t history;  //优化迭代历史目标值
};

using vecCase_t = std::vector<std::shared_ptr<Case_t>>;

//2.
struct StatBatch_t
{
    value_t meanY;                         //y的均值
    value_t stdY;                          //y的标准差
    std::shared_ptr<Case_t> bestCase;      //最好的一次求解
    std::shared_ptr<Case_t> worstCase;     //最差的一次求解
    std::shared_ptr<Case_t> medianCase;    //排序为中位数的解
    std::shared_ptr<BaseFun> fun;          //测试函数
    std::shared_ptr<BaseSolver> solver;    //测试求解器
    std::shared_ptr<Condition_t> condition;//测试条件
    vecCase_t vecCase;                     //所有测试频次
};
using listStatBatch_t = std::list<std::shared_ptr<StatBatch_t>>;
using vecStatBatch_t  = std::vector<std::shared_ptr<StatBatch_t>>;
using mapPairBatch_t  = std::map<std::pair<FunType_E, SolverType_E>, std::shared_ptr<StatBatch_t>>;

//2. 统计类
class Statistics
{
public:
    Statistics();
    ~Statistics();

    //保存当前case信息到文件
    bool saveCase(const std::string &f) const;

    //从文件载入case信息,执行此操作后当前结构的所有变量将重置
    bool loadCase(const std::string &f);

    //案例测试
    void testCase(  const vecSolverType_t &solverTypes, 
                    const vecFunType_t &funTypes,  
                    const Condition_t &con, 
                    const std::size_t dim,       //变量维度
                    const value_t minVar,        //变量下限
                    const value_t maxVar,        //变量上限
                    const uint32_t testNum = 1,  //函数测试次数
                    const uint16_t threadNum = 1);

public:
    void readCondition(File &fr, Condition_t &con) const;

    void writeCondition(File &fw, const Condition_t &con) const;

    void readBatch(File &fr, std::shared_ptr<StatBatch_t> &batch, const vecBaseFun_t &funs, const vecBaseSolver_t &solvers, const vecCondition_t &conditions) const;

    void writeBatch(File &fw, const std::shared_ptr<StatBatch_t> &batch) const;

    //更新统计批次的基本参数
    void updateStatBatch(std::shared_ptr<StatBatch_t> &batch) const;

    std::shared_ptr<StatBatch_t> createBatch(FunType_E funType, SolverType_E solverType, const Condition_t &con, const std::size_t dim, const value_t minVar, const value_t maxVar) const;

    inline void pushMapBatch(listStatBatch_t &listBatch, mapPairBatch_t &mapBatch) const;

    inline std::shared_ptr<Case_t> createCase(std::shared_ptr<BaseSolver> &solver) const;

private:
    vecStatBatch_t vecBatch_;
};

}